package com.jinxinol.core.util;

import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Node;

/**
 * <p>用于产生XML文本的工具类。</p>
 * 
 */
public abstract class XMLGenerator {

	private static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	public static String toXML(String rootName, Object obj) {
		XMLObject xmlObject = new XMLObject("response", true);
		XMLGenerator.addObject(xmlObject, xmlObject.getRootNode(), obj);
		return xmlObject.toXML();
	}
	
	@SuppressWarnings({ "rawtypes" })
	private static void addObject(XMLObject xmlObject, Node parentNode, Object obj) {
		
		if (obj == null) {
			obj = "";
		}
		
		// 处理数组类型
		if (ClassTypeUtils.isArray(obj)) {
			XMLGenerator.addArray(xmlObject, parentNode, (Object[])obj);
		}
		// 处理Map类型的对象
		if (ClassTypeUtils.isMap(obj)) {
			XMLGenerator.addMap(xmlObject, parentNode, (Map)obj);
		}
		// 处理List类型的对象
		else if (ClassTypeUtils.isList(obj)) {
			XMLGenerator.addList(xmlObject, parentNode, (List)obj);
		}
		// 处理日期类型
		else if (ClassTypeUtils.isDate(obj)) {
			XMLGenerator.addDate(xmlObject, parentNode, (Date)obj);
		}
		// 处理简单类型和基本类型的对象
		else if (ClassTypeUtils.isBase(obj) || ClassTypeUtils.isSimple(obj) || ClassTypeUtils.isEnum(obj)) {
			XMLGenerator.addBase(xmlObject, parentNode, obj);
		}
		// 处理复杂类型的对象
		else {
			XMLGenerator.addComplex(xmlObject, parentNode, obj);
		}
		
	}
	
	private static void addArray(XMLObject xmlObject, Node parentNode, Object[] objArray) {
		for (Object obj : objArray) {
			Node node = xmlObject.createElement(parentNode, "value");
			XMLGenerator.addObject(xmlObject, node, obj);
		}
	}
	
	@SuppressWarnings({ "rawtypes" })
	private static void addMap(XMLObject xmlObject, Node parentNode, Map map) {
		for (Object key : map.keySet()) {
			Node node = xmlObject.createElement(parentNode, key.toString());
			Object value = map.get(key);
			XMLGenerator.addObject(xmlObject, node, value);
		}
	}
	
	@SuppressWarnings({ "rawtypes" })
	private static void addList(XMLObject xmlObject, Node parentNode, List list) {
		for (Object value : list) {
			Node node = xmlObject.createElement(parentNode, "value");
			XMLGenerator.addObject(xmlObject, node, value);
		}
	}
	
	private static void addDate(XMLObject xmlObject, Node parentNode, Date date) {
		String value = XMLGenerator.df.format(date).toString();
		xmlObject.setNodeText(parentNode, value);
	}
	
	private static void addBase(XMLObject xmlObject, Node parentNode, Object obj) {
		try {
			Method method = obj.getClass().getMethod("toString", new Class[0]);
			String value = method.invoke(obj).toString();
			xmlObject.setNodeText(parentNode, value);
		} catch (Exception e) {
			System.out.println("not a base type");
		}
	}
	
	private static void addComplex(XMLObject xmlObject, Node parentNode, Object obj) {
		Method methods[] = obj.getClass().getMethods();
		for (Method method : methods) {
			String methodName = method.getName();
			if(methodName.startsWith("get") && !methodName.equals("getClass") && method.getParameterTypes().length==0)
			{
				Node node = xmlObject.createElement(parentNode, methodName.substring(3));
				try {
					Object value = method.invoke(obj);
					XMLGenerator.addObject(xmlObject, node, value);
				} catch (Exception e) {
					System.out.println("can not invoke method : " + methodName);
				}
			}
		}
	}
	
}
